#include <iostream>
#include <cstring>
#include <unistd.h>
#include <pthread.h>
#include "RingQueue.hpp"
#include "Task.hpp"

using namespace std;

void *producersRoutine(void *arg)
{
    // 生产者生产数据

    RingQueue<TaskCalc<int>> *rq = static_cast<RingQueue<TaskCalc<int>> *>(arg);
    while (true)
    {
        int x = rand() % 100;
        int y = rand() % 100;

        const char *ps = "+-*/%";
        char op = ps[rand() % strlen(ps)];

        TaskCalc<int> tc(x, y, op);

        rq->push(tc);
        cout << "Produce done: " << tc.formatArgs() << endl;
        sleep(1);
    }
}

void *consumersRoutine(void *arg)
{
    // 消费者消费数据

    RingQueue<TaskCalc<int>> *rq = static_cast<RingQueue<TaskCalc<int>> *>(arg);
    while (true)
    {
        TaskCalc<int> tc;
        rq->pop(&tc);
        tc();

        cout << "Consumer done: " << tc.formatResult() << endl;
    }
}

int main()
{
    // 单生产者、单消费者模型
    RingQueue<TaskCalc<int>> *rq = new RingQueue<TaskCalc<int>>();

    // // 创建生产者、消费者线程
    // // Producers, consumers
    // pthread_t pro, con;
    // pthread_create(&pro, nullptr, producersRoutine, rq);
    // pthread_create(&con, nullptr, consumersRoutine, rq);

    // // 等待线程运行结束
    // pthread_join(pro, nullptr);
    // pthread_join(con, nullptr);

    // 多线程版
    int p = 5, c = 3;
    pthread_t pp[p];
    pthread_t cc[c];

    for (int i = 0; i < p; i++)
        pthread_create(pp + i, nullptr, producersRoutine, rq);

    for (int i = 0; i < c; i++)
        pthread_create(cc + i, nullptr, consumersRoutine, rq);


    for (int i = 0; i < p; i++)
        pthread_join(pp[i], nullptr);

    for (int i = 0; i < c; i++)
        pthread_join(cc[i], nullptr);

    delete rq;
    return 0;
}